#include <stdio.h>  
#include <stdlib.h>
#include <assert.h>

/* --- Global Variables ---------------------------------------------------- */
int memcount = 0;

/* --- Data Structures ----------------------------------------------------- */
struct node  
{  
	int data;  
	struct node *next;  
} *head;

void *my_malloc (size_t s)
{
	void *s1 = malloc(s);
	assert(s1 != NULL);
	++memcount;
	return s1;
}

void my_free(void *ptr){
	free(ptr);  
	--memcount;
}

/* --- Stack functionality ------------------------------------------------- */
int pop()  
{
	assert(head != NULL);
	
	struct node *cur_ptr = head;
	int data = head->data;
	head = head->next;
	my_free(cur_ptr);
	
	return data;
}

void displayStack()  
{
	assert(head != NULL);

	struct node *cur_ptr = head;  
	printf("\nElements in Stack:\n");  
	while(cur_ptr != NULL)
	{  
		printf("\t%d\n",cur_ptr->data);  
		cur_ptr = cur_ptr->next;  
	}  
	printf("\n");  
}  

void push(int data)
{  
	struct node *tmp = (struct node*) my_malloc (sizeof( struct node) );
	tmp->data = data;  

	if(head != NULL) {
		tmp->next = head;  
		head = tmp;  
	}  
	else { //List is empty  
		head = tmp;  
		head->next = NULL;  
	}  
} 
 
int size(){
	if( head == NULL ) {
		return 0;
	}
	
	struct node *cur_ptr = head;
	int size = 1;

	while( cur_ptr->next != NULL ){
		cur_ptr = cur_ptr->next;
		++size; 
	}
	
	return size;
}
int main(){
	int i = 0, bound = 100;
	
	for(i=0; i < bound; ++i){
		push(i);
		#ifndef __VERIFY
			assert(size()==i+1); 
		#endif
	}

	displayStack();

	for(i=0; i<bound; ++i){
		#ifndef __VERIFY
			assert(size() == bound-i);
		#endif
		assert(pop() == bound-i-1);
	}
	assert( memcount == 0); // No memory leaks
}
